package net.xdclass.service.impl;

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import net.xdclass.constant.CacheKey;
import net.xdclass.enums.BizCodeEnum;
import net.xdclass.exception.BizException;
import net.xdclass.interceptor.LoginInterceptor;
import net.xdclass.mapper.CartMapper;
import net.xdclass.model.LoginUser;
import net.xdclass.request.CartItemRequest;
import net.xdclass.service.CartService;
import net.xdclass.service.ProductService;
import net.xdclass.vo.CartItemVO;
import net.xdclass.vo.CartVO;
import net.xdclass.vo.ProductVO;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
@Slf4j
public class CartServiceImpl implements CartService {

    @Autowired
    private CartMapper cartMapper;

    @Autowired
    private ProductService productService;

    @Autowired
    private RedisTemplate redisTemplate;


    /**
     * 添加商品到购物车
     */
    @Override
    public void cartAdd(CartItemRequest cartItemRequest) {
        long productId = cartItemRequest.getProductId();
        int buyNum = cartItemRequest.getBuyNum();
        BoundHashOperations<String, Object, Object> cart = getCart();
        Object o = cart.get(productId);
        String result = "";
        result = (String) o;
        if (StringUtils.isBlank(result)) {
            ProductVO detail = productService.detail(productId);
            if (detail == null) {
                throw new BizException(BizCodeEnum.CART_FAIL);
            }
            CartItemVO cartItemVO = new CartItemVO();
            cartItemVO.setAmount(detail.getAmount());
            cartItemVO.setBuyNum(buyNum);
            cartItemVO.setProductId(productId);
            cartItemVO.setProductTitle(cartItemVO.getProductTitle());
            cart.put(productId,JSON.toJSONString(cartItemVO));
        } else {
            CartItemVO cartItemVO = JSON.parseObject(result, CartItemVO.class);
            cartItemVO.setBuyNum(cartItemVO.getBuyNum() + buyNum);
            cart.put(productId,JSON.toJSONString(cartItemVO));
        }
    }

    /**
     * 清空购物车
     */
    @Override
    public void delete() {
        String cartKey = getCartKey();
        redisTemplate.delete(cartKey);
    }

    /**
     * 查询购物车
     * @return
     */
    @Override
    public CartVO queryCart() {

        //获取全部购物项
        List<CartItemVO> cartItemVOS = buildCart(false);
        //封装成cartVo
        CartVO cartVO = new CartVO();
        cartVO.setCartItems(cartItemVOS);
        return cartVO;
    }

    /**
     * 删除购物车某一项
     * @param productId
     */
    @Override
    public void deleteItem(long productId) {
        BoundHashOperations<String, Object, Object> myCart = getCart();
        myCart.delete(productId);
    }

    /**
     * 修改购物车 商品数量
     * @param cartItemRequest
     */
    @Override
    public void change(CartItemRequest cartItemRequest) {
        BoundHashOperations<String, Object, Object> myCart = getCart();
        Object obj = myCart.get(cartItemRequest.getProductId());
        if (obj == null) {
            throw new BizException(BizCodeEnum.CART_FAIL);
        }
        String json = (String)obj;
        CartItemVO cartItemVO = JSON.parseObject(json, CartItemVO.class);
        cartItemVO.setBuyNum(cartItemRequest.getBuyNum());
        myCart.put(cartItemRequest.getProductId(), JSON.toJSONString(cartItemVO));
    }

    private List<CartItemVO> buildCart(boolean lastedFlag) {
        BoundHashOperations<String, Object, Object> myCart = getCart();
        List<Object> values = myCart.values();
        List<CartItemVO> cartList = new ArrayList<>();
        List<Long> productIdList = new ArrayList<>();
        for (Object o : values) {
            CartItemVO cartItemVO = JSON.parseObject((String) o, CartItemVO.class);
            cartList.add(cartItemVO);
            productIdList.add(cartItemVO.getProductId());
        }
        if(lastedFlag){
            setLastedPrice(cartList,productIdList);
        }

        return cartList;
    }

    private void setLastedPrice(List<CartItemVO> cartList,List<Long> productIdList){
        List<ProductVO> productVOList = productService.selectProductByIdList(productIdList);
        Map<Long, ProductVO> maps = productVOList.stream().collect(Collectors.toMap(ProductVO::getId, Function.identity()));
        cartList.stream().forEach(item->{
            ProductVO productVO = maps.get(item.getProductId());
            item.setProductTitle(productVO.getTitle());
            item.setProductImg(productVO.getCoverImg());
            item.setAmount(productVO.getAmount());
        });

        }
    /**
     * 得到redis中的购物车信息
     * @return
     */
    private BoundHashOperations<String,Object,Object> getCart() {
        String cartKey = getCartKey();
        return redisTemplate.boundHashOps(cartKey);
    }

    /**
     * 得到购物车key+
     * @return
     */
    private String getCartKey() {
        LoginUser loginUser = LoginInterceptor.threadLocal.get();
        return String.format(CacheKey.CART_KEY, loginUser.getId());
    }
}
